package com.vsen.lpr.controller;

import com.google.api.client.util.Lists;
import com.vsen.lpr.common.model.Response;
import com.vsen.lpr.common.utils.MinioTemplate;
import com.vsen.lpr.config.BucketNameConfig;
import com.vsen.lpr.config.FilesConfig;
import com.vsen.lpr.pojo.vo.file.UploadVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import static com.vsen.lpr.common.exception.ErrorEnum.VALIDATED_ERROR;

/**
 * 文件上传
 */
@RestController
@RequestMapping("/file")
public class UploadFilesController {

    private final Log log = LogFactory.getLog(UploadFilesController.class);
    @Autowired
    private MinioTemplate minioTemplate;
    @Autowired
    private FilesConfig config;

    /**
     * 上传文件
     *
     * @param upfile 上传的文件对象
     * @return
     */
    @PostMapping("upload")
    public Response<Object> upload(@RequestParam("upfile") MultipartFile upfile) {
        String fileName = upfile.getOriginalFilename();
        String bucketName = "lpr";
        String perfixName = "/";
//        Integer dateFile = 1;//是否需要创建文件夹
        try {
            fileCheck(upfile, fileName);
        } catch (Exception e) {
            return Response.error(VALIDATED_ERROR);
        }
        if (StringUtils.isBlank(fileName)) {
            return Response.error(VALIDATED_ERROR);
        }
        StringBuilder sbFile = new StringBuilder();
        if (StringUtils.isNotBlank(perfixName)) {
            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
        }
        sbFile.append("banner");
        sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
//        if (dateFile != null && dateFile == 1) {
//            // 创建时间文件夹
//            sbFile.append(BucketNameConfig.getYear());
//            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
//            sbFile.append(BucketNameConfig.getMonthAndDay());
//            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
//        }
        sbFile.append(fileName);
        fileName = sbFile.toString();
        try {
            minioTemplate.createBucket(bucketName);
            minioTemplate.putObject(bucketName, fileName, upfile.getInputStream(),upfile.getSize(),"image/png");
            UploadVo result = new UploadVo();

            result.setFileUrl(config.getHttpUrl() + "?bucketName=" + bucketName + "&objectName=" + fileName);
            result.setBucketName(bucketName);
            result.setObjectName(fileName);
            return Response.success(result);
        } catch (Exception e) {
            log.error("文件上传异常", e);
            return Response.error();
        }
    }


    /**
     * 多上传文件
     *
     * @param upfileList 上传的文件对象集合
     * @param bucketName 所属的存储桶（第一级目录）
     * @return
     */
    @PostMapping("fileList")
    public Response<Object> uploadList(@RequestParam("upfileList") List<MultipartFile> upfileList,
                                       String bucketName,
                                       String perfixName,
                                       Integer dateFile) {
        if (StringUtils.isBlank(bucketName)) {
            return Response.error(VALIDATED_ERROR);
        }
        List<UploadVo> resultList = Lists.newArrayList();
        StringBuilder sbFile = new StringBuilder();
        if (StringUtils.isNotBlank(perfixName)) {
            sbFile.append(perfixName).append(BucketNameConfig.FILE_SPLIT_PATH);
        }
        if (dateFile != null && dateFile == 1) {
            // 创建时间文件夹
            sbFile.append(BucketNameConfig.getYear());
            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
            sbFile.append(BucketNameConfig.getMonthAndDay());
            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
        }
        for (MultipartFile file : upfileList) {
            String fileName = file.getOriginalFilename();
            try {
                fileCheck(file, fileName);
            } catch (Exception e) {
                Response.error();
            }
            fileName = sbFile.toString() + fileName;
            try {
                minioTemplate.createBucket(bucketName);
                minioTemplate.putObject(bucketName, fileName, file.getInputStream());
                UploadVo result = new UploadVo();
                result.setFileUrl(config.getHttpUrl() + "?bucketName=" + bucketName + "&objectName=" + fileName);
                result.setBucketName(bucketName);
                result.setObjectName(fileName);
                resultList.add(result);
            } catch (Exception e) {
                log.error("文件上传异常", e);
                return Response.error();
            }
        }
        return Response.success(resultList);
    }

    /**
     * 文件流下载
     *
     * @param objectName 文件对象名称
     * @param response
     */
    @PostMapping("/download")
    public void downloadIo(@RequestParam("objectName")  String objectName, HttpServletResponse response) {
        String bucketName = "lpr";
        javax.servlet.ServletOutputStream out = null;
        try (InputStream inputStream = minioTemplate.getObject(bucketName, objectName)) {
            response.setHeader("Content-Disposition", "attachment;filename=" + objectName.substring(objectName.lastIndexOf("/") + 1));
            response.setContentType("application/force-download");
            response.setCharacterEncoding("UTF-8");
            out = response.getOutputStream();
            byte[] content = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(content)) != -1) {
                out.write(content, 0, length);
            }
            out.flush();
        } catch (Exception e) {
            log.error("文件读取异常", e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    log.error("文件流关闭异常", e);
                }
            }
        }
    }


    /**
     * 文件流下载
     *
     * @param objectName 文件对象名称
     */
    @PostMapping("/download2")
    public Response<String> downloadIo(@RequestParam("objectName")  String objectName) {
        String bucketName = "lpr";
        String url =  minioTemplate.getObjectURL(bucketName,objectName);
        return Response.success(url);
    }


    /**
     * 判断是否图片
     */
    private boolean isImage(String fileName) {
        //设置允许上传文件类型
        String suffixList = "jpg,gif,png,ico,bmp,jpeg";
        // 获取文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf(".")
                + 1, fileName.length());
        if (suffixList.contains(suffix.trim().toLowerCase())) {
            return true;
        }
        return false;
    }

    /**
     * 验证文件大小
     *
     * @param upfile
     * @param fileName 文件名称
     * @throws Exception
     */
    private void fileCheck(MultipartFile upfile, String fileName) throws Exception {
        Long size = upfile.getSize();
        if (isImage(fileName)) {
            if (size > config.getImgSize()) {
                throw new Exception("上传对图片大于：" + (config.getImgSize() / 1024 / 1024) + "M限制");
            }
        } else {
            if (size > config.getFileSize()) {
                throw new Exception("上传对文件大于：" + (config.getFileSize() / 1024 / 1024) + "M限制");
            }
        }
    }

//    /**
//     * 上传文件
//     *
//     * @param file 文件
//     * @return
//     */
//    public Response uploadFile(MultipartFile file) throws Exception {
//        JSONObject res = new JSONObject();
//        res.put("code", 500);
//        // 判断上传文件是否为空
//        if (null == file || 0 == file.getSize()) {
//            res.put("msg", "上传文件不能为空");
//            return res;
//        }
//        // 判断存储桶是否存在
//        if (!client.bucketExists("test")) {
//            client.makeBucket("test");
//        }
//        // 拿到文件后缀名，例如：png
//        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
//        // UUID 作为文件名
//        String uuid = String.valueOf(UUID.randomUUID());
//        // 新的文件名
//        String fileName = DateUtils.getYyyymmdd() + "/" + uuid + "." + suffix;
//        /**
//         * 判断是否是图片
//         * 判断是否超过了 100K
//         */
//        if (isPicture(suffix) && (1024 * 1024 * 0.1) <= file.getSize()) {
//            // 在项目根目录下的 upload 目录中生成临时文件
//            File newFile = new File(ClassUtils.getDefaultClassLoader().getResource("upload").getPath() + uuid + "." + suffix);
//            // 小于 1M 的
//            if ((1024 * 1024 * 0.1) <= file.getSize() && file.getSize() <= (1024 * 1024)) {
//                Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.3f).toFile(newFile);
//            }
//            // 1 - 2M 的
//            else if ((1024 * 1024) < file.getSize() && file.getSize() <= (1024 * 1024 * 2)) {
//                Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.2f).toFile(newFile);
//            }
//            // 2M 以上的
//            else if ((1024 * 1024 * 2) < file.getSize()) {
//                Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.1f).toFile(newFile);
//            }
//            // 获取输入流
//            FileInputStream input = new FileInputStream(newFile);
//            // 转为 MultipartFile
//            MultipartFile multipartFile = new MockMultipartFile("file", newFile.getName(), "text/plain", input);
//            // 开始上传
//            client.putObject("test", fileName, multipartFile.getInputStream(), file.getContentType());
//            // 删除临时文件
//            newFile.delete();
//            // 返回状态以及图片路径
//            res.put("code", 200);
//            res.put("msg", "上传成功");
//            res.put("url", minioProp.getEndpoint() + "/" + "test" + "/" + fileName);
//        }
//        // 不需要压缩，直接上传
//        else {
//            // 开始上传
//            client.putObject("test", fileName, file.getInputStream(), file.getContentType());
//            // 返回状态以及图片路径
//            res.put("code", 200);
//            res.put("msg", "上传成功");
//            res.put("url", minioProp.getEndpoint() + "/" + "test" + "/" + fileName);
//        }
//        return res;
//    }



}